#!@LUA@

-- globals used only in core/packagemanager, soon to be deprecated
SYSTEM_SILE_PATH = "@SILE_PATH@"
SHARED_LIB_EXT = "@SHARED_LIB_EXT@"

local executable = debug.getinfo(1, "S").source
local luaversion = _VERSION:match("%d+%.%d+")

local function prependPath (path)
  package.path  = path .. "/?/init.lua;" .. package.path
  package.path  = path .. "/?.lua;" .. package.path
end

local function prependCPath (path)
  package.cpath = path .. "/?.@SHARED_LIB_EXT@;" .. package.cpath
end

local function extendPaths (path, ours)
  prependCPath(path)
  prependPath(path)
  if ours then
    prependPath(path .. "/lua-libraries")
    if "@SYSTEM_LUAROCKS_FALSE@" == "" then -- see ./configure --with[out]-system-luarocks
      prependCPath(path .. "/lua_modules/lib/lua/" .. luaversion)
      prependPath(path .. "/lua_modules/share/lua/" .. luaversion)
    end
  else
    prependCPath(path .. "/sile")
    prependPath(path .. "/sile")
  end
end

-- Facilitate loading SILE classes & packages from system LuaRocks
-- Also weed out CWD relative paths, we add them in a different order later
local luapath = {}
local extpath = {}
for path in package.path:gmatch("[^;]+") do
  -- We want to add `./?` back in an earlier slot but leave Nix Fake's "./shared"
  if not path:match("^./%?") and path:len() >= 1 then
    table.insert(extpath, tostring(path:gsub("?", "sile/?")))
    table.insert(luapath, path)
  end
end
package.path = table.concat(luapath, ";")

extendPaths("@SILE_PATH@", true)
extendPaths("@SILE_LIB_PATH@", true)

package.path = table.concat(extpath, ";") .. ";" .. package.path

local pathvar = os.getenv("SILE_PATH")
if pathvar then
  for path in string.gmatch(pathvar, "[^;]+") do
    if not path:match("^./") and path:len() >= 1 then
      extendPaths(path)
    end
  end
end

local cwd = executable:gsub("(.*)(/.*)", "%1")
if cwd:match("^@") then -- Consider "ours" for the sake of Nix Flake
  extendPaths(".", true)
else
  if cwd ~= "./" then extendPaths(cwd) end
  extendPaths(".")
end

-- This global is set here and *also* in the core library, since this
-- effectively passes the same table they are interchangeable (for now).
SILE = require("core.sile")

io.stdout:setvbuf 'no'

SILE.cli:parseArguments()

if not os.getenv 'LUA_REPL_RLWRAP' then
  io.stderr:write(SILE.full_version .. '\n')
end

local ProFi
if SU.debugging("profile") then
  ProFi = require("ProFi")
end

if SILE.makeDeps then
  SILE.makeDeps:add(executable)
end

SILE.init()

if SILE.masterFilename then

  extendPaths(SILE.masterDir)

  if SU.debugging("profile") then
    ProFi:start()
  end

  -- Deprecated, notice given in core.cli when argument used
  for _, path in ipairs(SILE.input.includes) do
    io.stderr:write("Loading "..path.."\n")
    local c = SILE.resolveFile(path, "classes")
    if c then
      SILE.processFile(c)
    else
      SILE.require(path, "classes")
    end
  end

  for _, spec in ipairs(SILE.input.uses) do
    SILE.use(spec.module, spec.options)
  end

  local main, err = xpcall(function()
    return SILE.processFile(SILE.input.filename)
  end, SILE.errorHandler)

  if not main then
    if type(err) == "string" and err:match(": interrupted!") then
      SILE.outputter:finish()
    else
      io.stderr:write("\nerror summary:\n\t" .. tostring(err) .. "\n")
    end
    os.exit(1)
  end

  SILE.finish()

  if SU.debugging("profile") then
    ProFi:stop()
    ProFi:writeReport(SILE.masterFilename..'.profile.txt')
  end

  if SU.debugging("versions") then
    SILE.shaper:debugVersions()
  end

else
  SILE.repl:enter()
end

-- vim: ft=lua
